/*
 * Copyright 2011 J. Auer, J. Andert, F.-J. Jendrusch, U. Celebi
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.fuberlin.replication.storage.jdbc.sqlite;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import de.fuberlin.replication.storage.MetadataDAO;
import de.fuberlin.replication.storage.Storage;
import de.fuberlin.replication.storage.SubsetDAO;
import de.fuberlin.replication.storage.Transaction;

/**
 * Implementation of the Storage interface for SQLite on PCs. It uses {@link "http://www.zentus.com/sqlitejdbc/"} as
 * JDBC driver.
 */
public class SQLiteStorage implements Storage {
	private SQLiteDatabaseHelper helper;
	private SQLiteSubsetDAO subsetDAO;
	private SQLiteMetadataDAO metadataDAO;
	private String customAddress;

	/**
	 * Constructor.
	 * 
	 * @param customAddress A custom name for the DB.
	 */
	public SQLiteStorage(String customAddress) {
		this.customAddress = customAddress;
	}

	/**
	 * Constructor.
	 */
	public SQLiteStorage() {
	}

	private SQLiteDatabaseHelper getHelper() {
		if (helper == null)
			if (customAddress == null)
				helper = new SQLiteDatabaseHelper();
			else
				helper = new SQLiteDatabaseHelper(customAddress);

		return helper;
	}

	@Override
	public long getVersion() {
		Connection conn = getHelper().getConnection();

		long version = 0;
		try {
			Statement s = conn.createStatement();
			ResultSet res = s.executeQuery(
					"SELECT * FROM version");

			PreparedStatement prep;
			if (res.next()) {
				version = res.getLong(1);

				prep = conn.prepareStatement("UPDATE version SET version = ? WHERE version = ?");

				prep.setLong(2, version++);
				prep.setLong(1, version);
			} else {
				version = 1;
				prep = conn.prepareStatement("INSERT INTO version (version) VALUES (?)");
				prep.setLong(1, version);
			}

			prep.executeUpdate();
			prep.close();

			res.close();
			s.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return version;
	}

	@Override
	public SubsetDAO getSubsetDAO() {
		if (subsetDAO == null)
			subsetDAO = new SQLiteSubsetDAO(getHelper().getConnection());

		return subsetDAO;
	}

	@Override
	public MetadataDAO getMetadataDAO() {
		if (metadataDAO == null)
			metadataDAO = new SQLiteMetadataDAO(getHelper().getConnection());

		return metadataDAO;
	}

	@Override
	public void runTransactional(Transaction transaction) {
		throw new UnsupportedOperationException();
	}
}